use bytes::BufMut;
use bytes::Bytes;
use bytes::BytesMut;
use tools::error::buf_err::FromBufError;
use tools::error::buf_err::ToBufError;
use tools::types::bufs::FromBuf;
use tools::types::bufs::ToBuf;
use tools::utils::byte::split_on;
use tools::utils::byte::str_from_utf8_bytes;
use tracing::error;

use crate::untils::borrow::StrPtr;


///头内容的值..会提供得到一个和多个的方法.以及修改一个或多个的方法
///注意:转换过程当中.只有StrPrt数据结构转换成引用.&str 或 String 都转换成Owner
#[derive(Debug)]
pub enum HeaderValue {
	Borrow(StrPtr),
	Owner(String),
	Int(i32),
	// Url(Url,Option<Tag>),
	// Via(Via,HeaderValue<'a>),
	// MediaType(MediaType),
	None,
}

impl Default for HeaderValue {
	fn default() -> Self {
		Self::None
	}
}

impl HeaderValue {
	#[inline]
	pub(crate) fn with_owner(str: String) -> Self {
		Self::Owner(str)
	}

	#[inline]
	pub(crate) fn with_int(val: i32) -> Self {
		Self::Int(val)
	}

	#[inline]
	pub(crate) fn with_borrow(ptr: StrPtr) -> Self {
		Self::Borrow(ptr)
	}
}

impl FromBuf for HeaderValue {
	type From = Bytes;

	fn from_buf_all(from: Self::From) -> Result<Self, FromBufError>
	where
		Self: Sized,
	{
		let str = str_from_utf8_bytes(&from);
		Ok(Self::with_borrow(StrPtr::from_str(str)))
	}

	fn from_buf(from: &mut Self::From) -> Result<Self, FromBufError>
	where
		Self: Sized,
	{
		let buf = split_on(from, b'\r');
		Self::from_buf_all(buf)
	}
}

impl ToBuf for HeaderValue {
	type Target = BytesMut;

	fn write_to(&self, target: &mut Self::Target) -> Result<(), ToBufError> {
		match self {
			HeaderValue::Borrow(sp) => target.extend_from_slice(sp.as_bytes()),
			HeaderValue::Owner(str) => target.extend_from_slice(str.as_bytes()),
			HeaderValue::Int(val) => target.put_i32(*val),
			HeaderValue::None => {
				error!("None为没有任何值...需要检查是否异常!");
				return Err(ToBufError::new("value必须要有值"));
			}
		}

		Ok(())
	}
}

impl From<i32> for HeaderValue {
	#[inline]
	fn from(value: i32) -> Self {
		Self::with_int(value)
	}
}

impl From<String> for HeaderValue {
	fn from(value: String) -> Self {
		Self::with_owner(value)
	}
}
